package com.lightkits.wms.domain.rawmatstorage.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.lightkits.common.db.entity.WmDeliveryTicket;
import com.lightkits.common.db.entity.WmDeliveryTicketLine;
import com.lightkits.common.db.entity.WmExecuteLine;
import com.lightkits.common.db.entity.event.BdEventRecord;
import com.lightkits.framework.common.exception.LightKitsBizException;
import com.lightkits.framework.common.logging.Logger;
import com.lightkits.framework.common.logging.LoggerFactory;
import com.lightkits.framework.common.model.CheckResult;
import com.lightkits.framework.common.utility.object.ObjectUtil;
import com.lightkits.framework.common.utility.object.ParseUtil;
import com.lightkits.framework.soa.client.id.IDServiceClient;
import com.lightkits.framework.soa.client.id.GetGlobalIDRequestType;
import com.lightkits.framework.soa.client.id.GetGlobalIDResponseType;
import com.lightkits.wms.domain.rawmatstorage.service.CreateUpdatePara;
import com.lightkits.wms.domain.usuallyinterface.GetWmMoveTypeExecutor;
import com.lightkits.wms.dto.rawmatstorage.model.RawMatStorageDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * CreateUpdateParaService
 *
 * @author jing.wei@hand-china.com
 * Created on 2019/4/21 0:18
 */
@Service
public class CreateUpdateParaService implements CreateUpdatePara {
    private static final Logger LOGGER = LoggerFactory.getLogger(GetWmMoveTypeExecutor.class);

    private final IDServiceClient idAdapterService;

    @Autowired
    public CreateUpdateParaService(IDServiceClient idAdapterService) {
        this.idAdapterService = idAdapterService;
    }

    @Override
    public CheckResult<WmDeliveryTicket> createTicketHead(RawMatStorageDTO dto) {
        CheckResult<WmDeliveryTicket> checkResult = new CheckResult<>();
        checkResult.setSuccessful(true);
        try {
            WmDeliveryTicketLine line = new WmDeliveryTicketLine().selectById(dto.getTicketLineId());
            WmDeliveryTicket headTicket = new WmDeliveryTicket().selectById(line.getTicketId());
            List<WmDeliveryTicketLine> lines = new WmDeliveryTicketLine().selectList(new EntityWrapper()
                    .eq(WmDeliveryTicketLine.TICKET_ID, line.getTicketId()));
            lines.forEach(target -> {
                if (ObjectUtil.isEmpty(target.getInventoryQty())
                        && ObjectUtil.isEmpty(target.getQcNgQty())
                        && ObjectUtil.isEmpty(target.getReturnedQty())) {
                    checkResult.setSuccessful(false);
                }
            });
            if (checkResult.isSuccessful()) {
                headTicket.setTicketStatus("COMPLETE");
                //create Record
                List<BdEventRecord> records = new ArrayList<>();
                BdEventRecord record = this.createRecord("WM_DELIVERY_TICKET", headTicket.getId(),
                        "STASUS", "COMPLETE");
                records.add(record);
                headTicket.store(records);
            }
            checkResult.setData(headTicket);
        } catch (Exception e) {
            LOGGER.error("createTicketHead.error", e);
            throw new LightKitsBizException(e);
        }
        return checkResult;
    }

    @Override
    public CheckResult<WmDeliveryTicketLine> createTicketLine(RawMatStorageDTO dto) {
        CheckResult<WmDeliveryTicketLine> checkResult = new CheckResult<>();
        checkResult.setSuccessful(true);
        try {
            WmDeliveryTicketLine line = new WmDeliveryTicketLine().selectById(dto.getTicketLineId());
            line.setInventoryQty(new BigDecimal(dto.getInventoryQty()));
            line.setInventoryWarehouseId(ParseUtil.tryLongWithException(dto.getInventoryWarehouseId()));
            if (!ObjectUtil.isNullOrEmpty(dto.getInventoryWmAreaId())) {
                line.setInventoryWmAreaId(ParseUtil.tryLongWithException(dto.getInventoryWmAreaId()));
            }
            if (!ObjectUtil.isNullOrEmpty(line.getRemark())) {
                line.setRemark(line.getRemark().concat("|" + dto.getRemark()));

            } else {
                line.setRemark(dto.getRemark());
            }
            //create Record
            List<BdEventRecord> records = new ArrayList<>();
            BdEventRecord record = this.createRecord("WM_DELIVERY_TICKET_LINE", line.getId(),
                    "INVENTORY_QTY", dto.getInventoryQty());
            records.add(record);
            line.store(records);
            checkResult.setData(line);
        } catch (Exception e) {
            LOGGER.error("createTicketLine.error", e);
            throw new LightKitsBizException(e);
        }
        return checkResult;

    }

    @Override
    public CheckResult<WmExecuteLine> createExecuteLine(RawMatStorageDTO dto) {
        CheckResult<WmExecuteLine> checkResult = new CheckResult<>();
        checkResult.setSuccessful(true);
        // TODO: 事务隔离范围过大
        GetGlobalIDRequestType idRequest = new GetGlobalIDRequestType();
        idRequest.setCount(1);
        GetGlobalIDResponseType idResponse = idAdapterService.getGlobalId(idRequest);
        Iterator<Long> sfIds = idResponse.getIds().iterator();
        try {
            WmDeliveryTicketLine line = new WmDeliveryTicketLine().selectById(dto.getTicketLineId());
            WmDeliveryTicket head = new WmDeliveryTicket().selectById(line.getTicketId());
            WmExecuteLine wmExecuteLine = new WmExecuteLine();
            wmExecuteLine.setId(sfIds.next());
            wmExecuteLine.setDocumentType("WM_TICKET");
            wmExecuteLine.setDocumentId(head.getId());
            wmExecuteLine.setDocumentLineId(line.getId());
            wmExecuteLine.setExecuteType("INPUT");
            wmExecuteLine.setItemId(line.getItemId());
            wmExecuteLine.setUom(line.getUom());
            wmExecuteLine.setExecutedQty(new BigDecimal(dto.getInventoryQty()));
            wmExecuteLine.setExecutedTime(new Date());
            wmExecuteLine.setLotNumber(line.getLotCode());
            wmExecuteLine.setWarehouseId(line.getReceiveWarehouseId());
            wmExecuteLine.setWmAreaId(line.getReceiveWmAreaId());
            wmExecuteLine.setToWarehouseId(ParseUtil.tryLongWithException(dto.getInventoryWarehouseId()));

            if (!ObjectUtil.isNullOrEmpty(dto.getInventoryWmAreaId())) {
                wmExecuteLine.setToWmAreaId(ParseUtil.tryLongWithException(dto.getInventoryWmAreaId()));

            }
            wmExecuteLine.setOwnerType(dto.getOwnerType());
            if (!ObjectUtil.isNullOrEmpty(dto.getOwnerId())) {
                wmExecuteLine.setOwnerId(ParseUtil.tryLongWithException(dto.getOwnerId()));
            }
            //create Record
            List<BdEventRecord> records = new ArrayList<>();
            BdEventRecord record = this.createRecord("WM_EXECUTE_LINE", wmExecuteLine.getId(),
                    "EXECUTE_TYPE", "INPUT");
            records.add(record);
            wmExecuteLine.store(records);
            checkResult.setData(wmExecuteLine);
        } catch (Exception e) {
            LOGGER.error("createExecuteLine.error", e);
            throw new LightKitsBizException(e);
        }
        return checkResult;
    }

    private BdEventRecord createRecord(String objectType, Long objectId, String recordType,
                                       String keyValue) {
        BdEventRecord record = new BdEventRecord();
        try {
            record.setObjectType(objectType);
            record.setObjectId(objectId);
            record.setRecordType(recordType);
            record.setKeyValue(keyValue);
        } catch (Exception e) {
            LOGGER.error("createRecord.error", e);
            throw new LightKitsBizException(e);
        }
        return record;
    }

}
